<!-- 封装mapbox地图组件 -->
<template>
    <div :id="mapId" class="map" ref="mapRef"></div>
</template>

<script setup lang="ts">
import mapboxgl from 'mapbox-gl'
import type { StyleSpecification } from 'mapbox-gl';

// 响应式解构 必须用在defineProps的时候解构 否则无响应式
const { mapId, accessToken, options } = defineProps({
    // 地图令牌
    accessToken: {
        type: String,
        required: false
    },

    // 地图容器id 一个页面上id不能重复
    mapId: {
        type: String,
        default: "map",
        required: true
    },

    // 传入的地图初始化参数
    options: {
        type: Object,
        default: () => ({})
    }
});

const emits = defineEmits(['click', 'load'])

// 地图实例
let map: mapboxgl.Map | any = shallowRef(null)

// 地图容器实例
const mapRef = useTemplateRef('mapRef')

// 监测resize对象
let resizeObserver: any = null;

// 地图默认样式
const defaultGisStyle: StyleSpecification = {
    version: 8,
    sources: {
        m_mono: {
            type: 'raster',
            tiles: ['/tile/{z}/{x}/{y}.png'],
            tileSize: 256,
            attribution: '',
        },
    },
    glyphs: '../../static/glyphs/{fontstack}/{range}.pbf',
    layers: [
        {
            id: 'm_mono',
            type: 'raster',
            source: 'm_mono',
            minzoom: 0,
            maxzoom: 18,
        },
    ],
};

// 地图默认初始化参数
const defaultOptions: mapboxgl.MapOptions = {
    container: mapId,
    style: defaultGisStyle,
    center: [120.2191, 30.2202],
    zoom: 2.2,
    minZoom: 1,
    maxZoom: 18,
    antialias: true,
    pitch: 0,
    projection: 'globe',
    performanceMetricsCollection: false,
};

// 初始化地图
const initMap = () => {
    mapboxgl.accessToken = accessToken || 'defaut-token';
    map.value = new mapboxgl.Map({
        ...defaultOptions,
        ...options
    });

    // 容器尺寸变化时 自适应容器
    if (window.ResizeObserver) {
        resizeObserver = new ResizeObserver(() => map.value.resize());
        resizeObserver.observe(mapRef.value);
    }

    // 地图样式加载完成 添加各种效果
    map.value.on('style.load', () => {
        ElMessage({
            message: 'Map loaded successfully!',
            type: 'success'
        })

        map.value.addControl(new mapboxgl.ScaleControl()); //比例尺
        map.value.addControl(new mapboxgl.NavigationControl()); //缩放  
        map.value.addControl(new mapboxgl.FullscreenControl(), 'top-right'); //全屏
        // map.addControl(new mapboxgl.GeolocateControl()); //定位
        // map.addControl(new mapboxgl.AttributionControl()); //版权
        map.value.addControl(new mapboxgl.AttributionControl({
            customAttribution: '<a href="https://gaode.com" target="_blank">高德地图</a>'
        }));

        // 
        map.value.setFog({
            color: "rgb(186, 210, 235)",
            "high-color": "rgb(36, 92, 223)",
            "horizon-blend": 0.02,
            "space-color": "rgb(11, 11 ,25)",
            "star-intensity": 0.6,
        });

        // map.setSnow({
        //     density: 1,
        //     intensity: 0.5
        // });

        // map.setRain({
        //     density: 1,
        //     intensity: 0.3,
        //     "distortion-strength": 0.3,
        // });

        // map.setFog({
        //     "range": [0.8, 8],
        //     "color": "#dc9f9f",
        //     "horizon-blend": 0.5,
        //     "high-color": "#245bde",
        //     "space-color": "#000000",
        //     "star-intensity": 0.15
        // });
    });

    map.value.on('load', () => {
        emits('load', map.value)
    });

    // 暴露地图的单击事件
    map.value.on('click', (e: mapboxgl.MapMouseEvent) => {
        emits('click', e)
    });
}

// 暴露地图对象实例
defineExpose({
    $map: map,
})


onMounted(() => {
    initMap();
});

onUnmounted(() => {
    if (map.value) {
        map.value.remove();

        ElMessage.success('map destroyed')
    }
    if (resizeObserver) {
        // debugger
        if (mapRef.value) {
            resizeObserver.unobserve(mapRef.value)
        }

        resizeObserver.disconnect();

    }
});

</script>

<style lang="less" scoped>
.map {
    height: 100%;
    width: 100%;
}
</style>